package dog.gui;

import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;

import constants.CHANGE;
import constants.GUI_STATE;
import containers.Appointment;
import containers.Message;

import dog.gui.appointmentView.AppointmentPanel;
import dog.gui.calendar.CalendarPanel;
import dog.model.Model;
//This class should manage the frame in which panels are displayed.
public class GUI implements PropertyChangeListener
	{
	private Model model;
	public JFrame frame;
	private JPanel currentPanel;
	private int state;
	private NewsPanel newsPanel;
	
	public static void main(String[] a)
		{
		new GUI();
		}
	
	public GUI()
		{
		model = new Model(this,JOptionPane.showInputDialog("IP: ","127.0.0.1"));
		model.addPropertyChangeListener(this);
		
		newsPanel = new NewsPanel(model);
		
		state=GUI_STATE.LOGIN;
		frame = new JFrame("Calendar System 5000");
		frame.setResizable(false);
		frame.addWindowListener(new WindowAdapter(){
		public void windowClosing(WindowEvent evt) {
			dispose();
			System.exit(0);
			}});
		currentPanel = new LoginPanel(model);
		frame.add(currentPanel);
		frame.pack();
		frame.setVisible(true);
		}
	
	public void dispose()
		{
		model.dispose();
		}
	public void loginAccept(int personID)
		{
		JOptionPane.showMessageDialog(null,"Login Accepted \nYour userID:"+personID,"Result",JOptionPane.PLAIN_MESSAGE);
		model.gui_setAccessRange(model.getCurrentYear(), model.getCurrentWeek());
		model.gui_accessPerson(personID);
		showCalendar();
		}
	public void showCalendar() {
		model.removeAllPropertyChangeListeners();
		model.addPropertyChangeListener(this);
		model.gui_setAccessPerson(model.getPersonID());
		state=GUI_STATE.CALENDAR;
		changeState(new CalendarPanel(this,model,newsPanel));
		//model.gui_setAccessRange(model.getShownYear(), model.getShownWeek());
	}
	public void loginFailed()
		{
		JOptionPane.showMessageDialog(null,"Login Failed","Result",JOptionPane.PLAIN_MESSAGE);
		((LoginPanel)currentPanel).loginFailed();
		}
	public void appointmentAddSuccess()
		{
		((AppointmentPanel)currentPanel).appointmentAddSuccess();
		}
	
	public void appointmentAddFailure()
		{
		((AppointmentPanel)currentPanel).appointmentAddFailure();
		}
	//this indicates that stuff has been delivered after a request.
	public void appointmentsDelivered()
		{
		
		}
	//This indicates an answer to a request for a specific appointment
	public void specificAppointmentReceived(Appointment appointment,Message context)
		{
		if (state==GUI_STATE.APPOINTMENT)
			{
			((AppointmentPanel)currentPanel).close();
			}
		goToAppView(appointment,context);
		}

	@Override
	public void propertyChange(PropertyChangeEvent e)
		{
		String type = e.getPropertyName();
		if(type.equals(CHANGE.MESSAGE))
			{
			System.out.println("Message caught.");
			
			Message m = (Message)e.getNewValue();
			addMessage(m);
			}
		
		}
	//View a specific appointment. If the parameter is null, create a new one.
	public void goToAppView(Appointment appointment,Message context)
		{
		model.removeAllPropertyChangeListeners();
		model.addPropertyChangeListener(this);
		state=GUI_STATE.APPOINTMENT;
		changeState(new AppointmentPanel(appointment,model,context,newsPanel));
		}
	public void changeState(JPanel newPanel)
		{
		frame.remove(currentPanel);
		currentPanel = newPanel;
		frame.add(currentPanel);
		frame.pack();
		}

	public void serverDisconnected(boolean wasConnected)
		{
		if(wasConnected)
			JOptionPane.showMessageDialog(null,"The connection was lost! Try to reconnect later.","ERROR",JOptionPane.ERROR_MESSAGE);
		else
			JOptionPane.showMessageDialog(null,"No response from the server at that IP address. Ensure that the server is running and that you are connected to the network.","ERROR",JOptionPane.ERROR_MESSAGE);
		if (frame!=null)
			{
			frame.setVisible(false);
			frame.dispose();
			}
		System.exit(0);
		}
	public void addMessage(Message m)
		{
		MessagePanel mp = new MessagePanel(m, model,newsPanel);
		newsPanel.addMessage(mp);
		}
	public void removeMessage(Message m)
		{
		newsPanel.removeMessage(new MessagePanel(m, model,newsPanel));
		}
	}
